package com.D5Power.Editor
{
	import com.D5Power.D5Game;
	import com.D5Power.Editor.Event.ClickObjectEvent;
	import com.D5Power.Editor.Objects.NCharacterObject_MaEd;
	import com.D5Power.Editor.Shower.AlphaShower;
	import com.D5Power.Editor.Shower.MapTileShower;
	import com.D5Power.Editor.config.DrawType;
	import com.D5Power.Editor.config.MouseStatus;
	import com.D5Power.Objects.BuildingObject;
	import com.D5Power.Objects.GameObject;
	import com.D5Power.Objects.NCharacterObject;
	import com.D5Power.map.WorldMap;
	import com.D5Power.simulator.Simulator;
	import com.D5Power.net.D5ByteArray;
	import com.D5Power.utils.XYArray;
	
	import flash.display.BitmapData;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.utils.ByteArray;
	
	import org.aswing.JPanel;
	import org.aswing.LayoutManager;
	
	/**
	 * 地图显示器
	 */ 
	public class MapShower extends D5Game
	{
		/**
		 * 模拟器
		 */ 
		private var sim:Simulator;
		
		/**
		 * 小地图 
		 */
		private var _smallMap:SmallMap;
		
		/**
		 * 地图网格显示器
		 */ 
		private var _tileShower:MapTileShower;
		
		private var _alphaShower:AlphaShower;
		
		private var _hasAlphaMap:Boolean=false;
		
		/**
		 * 是否显示网格
		 */ 
		private var _showTile:Boolean = false;
		
		private var _showOver:Boolean = false;
		
		public var objectName:String='MapShower';
		
		private var _root:MapEditor;
		
		/**
		 * 透明转换区域
		 */ 
		private var _AlphaArea:Shape;
		
		/**
		 * 碰撞判断区域
		 */ 
		private var _HitArea:Shape;
		
		/**
		 * 绘制状态
		 */ 
		private var _drawStatus:uint;
		/**
		 * 绘制开始位置
		 */ 
		private var _drawStart:Point;
		/**
		 * 绘制路线
		 */ 
		private var _drawPath:Array;

		/**
		 * @param	layout	布局
		 * @param	_stage	主场景引用
		 */ 
		public function MapShower(config:String,stg:Stage,root:MapEditor=null)
		{
			_root = root;
			super(config,stg);
		}
		
		public function PAUSE():void
		{
			if(hasEventListener(Event.ENTER_FRAME))
			{
				removeEventListener(Event.ENTER_FRAME,render);
			}else{
				addEventListener(Event.ENTER_FRAME,render);
			}
		}
		
		public function reset():void
		{
			removeAllObject();
			clearTile();
		}
		
		override public function clear():void
		{
			reset();
			graphics.clear();
			removeEventListener(Event.ENTER_FRAME,render);
			if(_displayer!=null)
			{
				_displayer.removeEventListener(MouseEvent.CLICK,onClick);
				_displayer.bitmapData.dispose();
				removeChild(_displayer);
				_displayer = null;
			}
		}
		
		/**
		 * 开始向场景中增加游戏对象
		 * @param	b		素材资源
		 * @param	type	对象类型BLIST-建筑 NPCLIST-NPC
		 */ 
		public function startAddObject(b:String,type:String,resname:String):GameObject
		{
			if(b==null) return null;
			cancleAddObject();
			
			var obj:GameObject;
			switch(type)
			{
				case LibResource.MAP:
					obj=scene.createEditorBuilding(b,null,resname);
					break;
				case LibResource.CHARACTER:
					obj=_scene.createNPC(b,resname);
					break;
			}
			addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
			addEventListener(MouseEvent.CONTEXT_MENU,cancleAddObject);
			
			return obj;
		}
		
		/**
		 * 批量删除对象
		 * @param	type	批量删除类型 BLIST 建筑 NPCLIST NPC
		 */ 
		public function removeAllObject(type:String=''):void
		{
			if(_scene==null) return;
			var arr:Array = _scene.getAllObjects();
			for each(var obj:GameObject in arr)
			{
				if(type=='' || (type=='BLIST' && obj.objectName=='BuildingObject') || (type=='NPCLIST' && obj.objectName=='NCharacterObject'))
				{
					_scene.removeObject(obj);
					removeAllObject(type);
					return;
				}
			}
		}
		
		/**
		 * 删除路点
		 */ 
		public function clearTile():void
		{
			if(_scene==null) return;
			_scene.Map.resetRoad();
			_tileShower.updateRockBuffer();
		}
		
		override protected function init():void
		{
			D5Power.mapid = _scene.Map.mapid;

			
			_AlphaArea = new Shape();
			_HitArea = new Shape();
			
			
			_tileShower = new MapTileShower(scene);
			_alphaShower = new AlphaShower(_AlphaArea,scene);
			super.init();

			addChild(_AlphaArea);
			addChild(_HitArea);
			
			addEventListener(MouseEvent.CLICK,onClick);
			
			_root.showResource();
		}
		
		override protected function buildObjects():void
		{
			if(_data!=null)
			{
				_scene.Map.tileFormat = _data.tileFormat;
				_root.MapProp.setSceneBG(_data.tileFormat);
				
				for each(var npclist:* in _data.npc.obj)
				{
					var obj:NCharacterObject = _scene.createNPC(npclist.res+'.png',npclist.res,npclist.name,new Point(npclist.posx,npclist.posy));
					obj.uid = npclist.uid;
					//trace('RUN',npclist);
				}
				
				for each(var buildList:* in _data.build.obj)
				{
					if(buildList.res=='') continue;
					var bld:BuildingObject = _scene.createBuilding(Global.httpServer+'asset/map/map'+_scene.Map.mapid+'/'+buildList.res+'.png',buildList.res,new Point(buildList.posx,buildList.posy));
					bld.zero=new Point(buildList.centerx,buildList.centery);
					bld.canBeAtk = buildList.canBeAtk=='true' ? true : false;
					bld.zOrderF = buildList.zorder;
					
					scene.fallObject(new Point(buildList.posx,buildList.posy));
				}
				
				var i:uint=0;
				for each(var mapdata:String in _data.road.y)
				{
					var arr:Array = mapdata.split(',');
					for(var key:String in arr)
					{
						if(arr[key]=='') continue;
						if(_scene.Map.roadMap[i][int(key)]==undefined) continue;
						_scene.Map.roadMap[i][int(key)] = arr[key];
					}
					i++;
				}
				
				_tileShower.updateRockBuffer();
				
				if(_data.loopbg!=null) _scene.Map.loopBG = _data.loopbg;
				scene.lua_file=_data.lua;
				
				_root.MapProp.updateBGName(_data.loopbg);
				_root.MapProp.updateLuaName(_data.lua);
				
				_root.startSmallMap();
			}
		}
		
		override protected function buildScene():void
		{
			_scene  = new EditorScene(_root.stage);
		}
		
		/**
		 * 根据地图配置文件生成地图
		 * 
		 */ 
//		public function setup2(s:String=''):void
//		{
//			// 开始运行
//			setPreferredWidth(Global.W);
//			setPreferredHeight(Global.H);
//			
//			
//			
//			
//			
//			
//			if(s!='')
//			{
//				var data:XML = new XML(s);
//	
//				Global.W = data.sceneW;
//				Global.H = data.sceneH;
//				Global.TILE_SIZE.x = data.tileX;
//				Global.TILE_SIZE.y = data.tileY;
//				Global.MAPSIZE.x = data.mapW;
//				Global.MAPSIZE.y = data.mapH;
//				_scene.Map.mapid = data.id;
//				
//				_scene.Map.setup(); // 初始化地图
//				
//				_scene.Map.tileFormat = data.tileFormat;
//				_root.MapProp.setSceneBG(data.tileFormat);
//				
//				for each(var npclist:* in data.npc.obj)
//				{
//					var obj:NCharacterObject = startAddObject(Global.getCharacterRes(Global.LIBNAME+'_'+npclist.res),'NPCLIST',npclist.res) as NCharacterObject;
//					_scene.fallObject(new Point(npclist.posx,npclist.posy));
//				}
//				
//				for each(var buildList:* in data.build.obj)
//				{
//					var bld:BuildingObject = startAddObject(Global.getCharacterRes(Global.LIBNAME+'_'+buildList.res),'BLIST',buildList.res) as BuildingObject;
//					bld.zero=new Point(buildList.centerx,buildList.centery);
//					_scene.fallObject(new Point(buildList.posx,buildList.posy));
//				}
//				
//				var i:uint=0;
//				for each(var mapdata:String in data.road.y)
//				{
//					var arr:Array = mapdata.split(',');
//					for(var key:String in arr)
//					{
//						if(arr[key]=='') continue;
//						_scene.Map.roadMap[i][int(key)] = arr[key];
//					}
//					i++
//				}
//				
//				_tileShower.updateRockBuffer();
//				
//				if(data.loopbg!=null) _scene.Map.loopBG = data.loopbg;
//				_scene.lua_file=data.lua;
//				
//				_root.MapProp.updateBGName(data.loopbg);
//				_root.MapProp.updateLuaName(data.lua);
//			}
//		}
		
		/**
		 * 绘制特殊区域
		 */ 
		public function drawArea(type:uint,x:Number,y:Number):void
		{
			var target:Shape;
			var color:uint;
			switch(type)
			{
				case DrawType.ALPHA_AREA:
					target = _AlphaArea;
					color = 0xffffff;
					break;
				case DrawType.HIT_AREA:
					target = _HitArea;
					color = 0xff0000;
					break;
			}
			
			var p:Point = _scene.Map.getWorldPostion(x,y);
			if(_drawStart==null)
			{
				_hasAlphaMap = true; // 编辑过地图，将透明检测地图设置状态设置为true
				
				_drawStart = new Point(p.x,p.y);
				_drawPath = [];
				target.graphics.lineStyle(1,color);
				
				// 将target偏移到开始位置
				target.x = -_scene.Map.cameraView.x;
				target.y = -_scene.Map.cameraView.y;
				
				target.graphics.moveTo(p.x,p.y);
				return;
			}
			
			// 记录绘制点
			_drawPath.push(p);
			
			if(Point.distance(p,_drawStart)<10)
			{
				// 距离接近，结束绘制
				target.graphics.clear();
				target.graphics.beginFill(color);
				
				target.graphics.moveTo(_drawStart.x,_drawStart.y);
				var dp:Point;
				while(_drawPath.length)
				{
					dp = _drawPath.shift();
					target.graphics.lineTo(dp.x,dp.y);
				}
				target.graphics.endFill();
				
				_alphaShower.flush();
				target.graphics.clear();
				_drawStart = null;
				_drawPath = null;
			}else{
				target.graphics.lineTo(p.x,p.y);
			}
		}
		
		/**
		 * 生成当前地图的配置文件
		 */ 
		public function get Configer():String
		{
			var result:String = "<map>\n";
			result+="<id>"+(_scene==null ? D5Power.mapid : _scene.Map.mapid)+"</id>\n";						// 地图ID
			result+="<hasTile>"+D5Power.hasTile+"</hasTile>\n";			// 是否采用区块构图
			result+="<loopbg>"+(_scene==null ? '' : _scene.Map.loopBG)+"</loopbg>\n";
			result+="<tileFormat>"+(_scene==null ? '' : _scene.Map.tileFormat)+"</tileFormat>\n";
			result+="<sceneW>"+Global.W+"</sceneW>\n";
			result+="<sceneH>"+Global.H+"</sceneH>\n";
			result+="<tileX>"+Global.TILE_SIZE.x+"</tileX>\n";
			result+="<tileY>"+Global.TILE_SIZE.y+"</tileY>\n";
			result+="<mapW>"+Global.MAPSIZE.x+"</mapW>\n";
			result+="<mapH>"+Global.MAPSIZE.y+"</mapH>\n";
			result+="<lua>"+(_scene==null ? '' : scene.lua_file)+"</lua>\n";
			result+="<hasAlphaMap>"+int(_hasAlphaMap)+"</hasAlphaMap>";
			
			
			var obj:Array = _scene==null ? new Array() : _scene.getAllObjects();
			
			var res_npc:String = "\n\n<npc>\n";
			var res_bud:String = "\n\n<build>\n";
			for each(var o:GameObject in obj)
			{
				switch(o.objectName)
				{
					case 'NCharacterObject':
						var nco:NCharacterObject_MaEd = o as NCharacterObject_MaEd;
						res_npc+="<obj>\n";
						res_npc+="<res>"+nco.graphics.resName+"</res>\n";
						res_npc+="<posx>"+nco.startPos.x+"</posx>\n";
						res_npc+="<posy>"+nco.startPos.y+"</posy>\n";
						res_npc+="<name>"+nco.username+"</name>\n";
						res_npc+="<lua>"+nco.lua_filename+"</lua>\n";
						res_npc+="<uid>"+nco.uid+"</uid>\n";
						res_npc+="</obj>\n";
						break;
					case 'BuildingObject':
						var nbo:BuildingObject = o as BuildingObject;
						res_bud+="<obj>\n";
						res_bud+="<res>"+nbo.graphics.resName+"</res>\n";
						res_bud+="<canBeAtk>"+nbo.canBeAtk+"</canBeAtk>\n";
						res_bud+="<zorder>"+nbo.zOrderF+"</zorder>\n";
						res_bud+="<posx>"+nbo.Pos.x+"</posx>\n";
						res_bud+="<posy>"+nbo.Pos.y+"</posy>\n";
						res_bud+="<centerx>"+nbo.zero.x+"</centerx>\n";
						res_bud+="<centery>"+nbo.zero.y+"</centery>\n";
						res_bud+="</obj>\n";
						break;
				}
			}
			res_npc+="</npc>\n";
			res_bud+="</build>\n";
			
			result+=res_npc;
			result+=res_bud;
			
			
			if(_tileShower!=null) result+=_tileShower.getRoadXML();
			
			result+="</map>";
			return result;
		}
		
		public function get AlphaMap():BitmapData
		{
			if(!_hasAlphaMap) return null;
			return _alphaShower.buffer;
		}
		
		/**
		 * 生成服务器端配置文件
		 */ 
		public function get ServerConfig():ByteArray
		{
			var arr:Array = _scene.Map.roadMap;
			var maxX:uint = int(Global.MAPSIZE.x/WorldMap.tileWidth);
			var maxY:uint = int(Global.MAPSIZE.y/WorldMap.tileHeight);
			
			var data:D5ByteArray = new D5ByteArray();
			data.writeShort(maxX);
			data.writeShort(maxY);
			
			// 计算总共需要写入的字节数
			var maxLength:uint = Math.ceil(maxX*maxY/8);
			for(var i:uint = 0;i<maxLength;i++) data.writeByte(0);
			
			// 已写入4字节的文件头，因此，从第32字节开始写入地图数据
			var p:uint=32;
			for(var y:uint=0;y<arr.length;y++)
			{
				for(var x:uint = 0;x<arr[y].length;x++)
				{
					data.writeBitAt(p,arr[y][x]==0 ? false : true);
					p++;
				}
			}
			return data;
		}
		
		/**
		 * 取消增加游戏对象
		 * 本程序会恢复主场景的鼠标状态
		 */ 
		private function cancleAddObject(e:MouseEvent=null):void
		{
			scene.cancleCreateObject();
			removeEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
			removeEventListener(MouseEvent.CONTEXT_MENU,cancleAddObject);
			_root.mouseStatus='';
		}
		
		/**
		 * 渲染
		 */ 
		override protected function render(e:Event):void
		{
			super.render(e);
			if(_scene.isReady)
			{
				if(_showTile) _tileShower.render();
				if(_showOver) _alphaShower.render();
			}
		}
		
		/**
		 * 鼠标移动，若有待确认建筑则跟随
		 */ 
		private function onMouseMove(e:MouseEvent):void
		{
			if(scene.waitInsertObject!=null)
			{
				scene.waitInsertObject.Pos = _scene.Map.getWorldPostion(e.localX,e.localY);
				e.updateAfterEvent();
			}
		}
		
		/**
		 * 点击，若有待确认建筑，则放置
		 */ 
		private function onClick(e:MouseEvent):void
		{
			switch(_root.mouseStatus)
			{
				case '':
					break;
				case MouseStatus.DRAW_OVER:
					drawArea(DrawType.ALPHA_AREA,e.localX,e.localY);
					break;
				default:
					trace('Unset status Mouse:'+_root.mouseStatus);
					return;
					break;
			}
			
			var worldPos:Point = _scene.Map.getWorldPostion(e.localX,e.localY);
			var scenePos:Point = new Point(e.localX,e.localY);
			var tilePos:XYArray = WorldMap.Postion2Tile(worldPos);
				
			var obj:GameObject = _scene.perc.getClicker(scenePos);
			
			_root.proShower.setWorldPos(worldPos.x,worldPos.y);
			_root.proShower.setScenePos(scenePos.x,scenePos.y);
			_root.proShower.setTilePos(tilePos.x,tilePos.y);

			if(scene.waitInsertObject!=null)
			{
				scene.fallObject(worldPos);
				removeEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
				removeEventListener(MouseEvent.CONTEXT_MENU,cancleAddObject);
			}else if(_showTile){
				// 无待确认建筑，编辑路点
				var p:XYArray = WorldMap.Postion2Tile(worldPos);
				_tileShower.updateRock(p.x,p.y);
			}else if(obj!=null){
				// 网格处于关闭状态，且有点击目标，触发点击事件
				dispatchEvent(new ClickObjectEvent(ClickObjectEvent.CLICK,obj,e.localX,e.localY));
			}
		}
		
		/**
		 * 关联小地图
		 */ 
		public function set smallMap(s:SmallMap):void
		{
			_smallMap = s;
		}
		
		/**
		 * 获取游戏场景
		 */ 
		public function get scene():EditorScene
		{
			return (_scene as EditorScene);
		}
		
		/**
		 * 是否显示网格
		 */ 
		public function set showTile(f:Boolean):void
		{
			_showTile = f;
		}
		
		/**
		 * 是否显示遮蔽透明判断层
		 */ 
		public function set showOver(f:Boolean):void
		{
			_showOver = f;
		}
		
		
	}
}